package com.woniuxy.controller;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;

import com.woniuxy.config.AliPayConfig;
import com.woniuxy.entity.*;
import com.woniuxy.entity.VO.PayVO;
import com.woniuxy.entity.dto.CheckMoneyDTO;
import com.woniuxy.mapper.*;
import com.woniuxy.util.GetUserContent;
import com.woniuxy.util.ResponseData;
import com.woniuxy.util.ResponseEnum;
import com.woniuxy.util.SnowflakeIdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Map;
import java.util.UUID;


@RestController
@RequestMapping("alipay")
@Transactional(rollbackFor = Exception.class)
public class AlipayController {
    @Resource
    AliPayConfig aliPayConfig;
    @Autowired
    private
    CheckMoneyMapper checkMoneyMapper;
    @Autowired
    private RegisteredMapper registeredMapper;
    @Autowired
    private DrugMoneyMapper drugMoneyMapper;
    @Autowired
    private DrugPatientMapper drugPatientMapper;
    @Autowired
    private RechargeMoneyMapper rechargeMoneyMapper;
    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "utf-8";
    private static final String SIGN_TYPE = "RSA2";
    /**     * 支付接口 传入业务参数     * 支付是一个我向你要钱的过程，设置api参数就是为了，知道收钱的人是谁，
     *  * 当执行以后支付宝会返回一个登录页面，支付的人输入帐号密码。并且确定金额输入支付密码进行支付
     *  * @param aliPay     * @param httpResponse     * @throws Exception
     *  */    // 这里使用Get其实不是很恰当，应该使用post，这里为了调试方便使用Get
    @RequestMapping("/pay")
    public void pay(PayVO aliPay, HttpServletResponse httpResponse) throws Exception {
        // 1、根据支付宝的配置生成一个支付客户端 客户端用于去调用支付宝的API        // 官方写法
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        // 2、创建一个支付请求对象
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();        // 设置回调接口
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        // 商户订单号，商户网站订单系统中唯一订单号，必填，支付宝不允许有两个相同的订单号        // 使用uuid生成 避免重复
        //aliPay.setOut_trade_no(UUID.randomUUID().toString());

        CheckMoneyDTO checkMoneyDTO = checkMoneyMapper.queryCkNo(aliPay.getCkNo());
        if(checkMoneyDTO!=null) {
            String CkNo = aliPay.getCkNo();        // 付款金额，必填
            BigDecimal total_amount = checkMoneyDTO.getCkProjectPrice();        // 订单名称，必填
            String subject = checkMoneyDTO.getCkProjectName();       // 商品描述，可空
            String body = checkMoneyDTO.getCkProjectName();        // 设置 业务参数 是一个json对象
            // 这个json对象 支付宝后台回去识别，根据这些参数进行处理，例如 金额，订单名称，商品描述
            request.setBizContent("{\"out_trade_no\":\"" + CkNo + "\","
                    + "\"total_amount\":\"" + total_amount + "\","
                    + "\"subject\":\"" + subject + "\","
                    + "\"body\":\"" + body + "\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

            // 支付完以后跳转的地址

        //    request.setReturnUrl("http://localhost:8098/checkMoney");
            // 3. 客户端执行请求        // 客户端执行请求，拿到响应的结果，返回给浏览器
            String form = "";
            try {            // 调用阿里的SDK生成表单
                // 会收到支付宝的响应，响应的是一个页面，一开始是登陆，然后显示金额，让用户输入密码进行付款
                form = alipayClient.pageExecute(request).getBody();
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            httpResponse.setContentType("text/html;charset=" + CHARSET);
            // 直接将完整的表单html输出到页面
            httpResponse.getWriter().write(form);
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
            checkMoneyMapper.add(checkMoneyDTO);
            checkMoneyMapper.updateStatus(checkMoneyDTO.getCkNo());

        }}
    @RequestMapping("num")
    public void pay1(PayVO aliPay, HttpServletResponse httpResponse) throws Exception {
        // 1、根据支付宝的配置生成一个支付客户端 客户端用于去调用支付宝的API        // 官方写法
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        // 2、创建一个支付请求对象
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();        // 设置回调接口
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        // 商户订单号，商户网站订单系统中唯一订单号，必填，支付宝不允许有两个相同的订单号        // 使用uuid生成 避免重复
        //aliPay.setOut_trade_no(UUID.randomUUID().toString());
        Registered registered = registeredMapper.queryRsNo(aliPay.getRsNo());


        if(registered!=null) {
            String CkNo = aliPay.getRsNo();        // 付款金额，必填
            BigDecimal total_amount = registered.getPrice();        // 订单名称，必填
            String subject = registered.getRsName();       // 商品描述，可空
            String body = registered.getRsDepartment();        // 设置 业务参数 是一个json对象
            // 这个json对象 支付宝后台回去识别，根据这些参数进行处理，例如 金额，订单名称，商品描述
            request.setBizContent("{\"out_trade_no\":\"" + CkNo + "\","
                    + "\"total_amount\":\"" + total_amount + "\","
                    + "\"subject\":\"" + subject + "\","
                    + "\"body\":\"" + body + "\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

            // 支付完以后跳转的地址

            //    request.setReturnUrl("http://localhost:8098/checkMoney");
            // 3. 客户端执行请求        // 客户端执行请求，拿到响应的结果，返回给浏览器
            String form = "";
            try {            // 调用阿里的SDK生成表单
                // 会收到支付宝的响应，响应的是一个页面，一开始是登陆，然后显示金额，让用户输入密码进行付款
                form = alipayClient.pageExecute(request).getBody();
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            httpResponse.setContentType("text/html;charset=" + CHARSET);
            // 直接将完整的表单html输出到页面
            httpResponse.getWriter().write(form);
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
            registeredMapper.updateStatus(registered.getRsNo());
            Payment payment = new Payment();
            payment.setRfRegistrationId(registered.getId());
            payment.setRfPrice(registered.getPrice());
            payment.setRfNo(registered.getRsNo());

            registeredMapper.add(payment);


        }}
    @RequestMapping("/drug")
    public void pay3(PayVO aliPay, HttpServletResponse httpResponse) throws Exception {
        // 1、根据支付宝的配置生成一个支付客户端 客户端用于去调用支付宝的API        // 官方写法
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        // 2、创建一个支付请求对象
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();        // 设置回调接口
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        // 商户订单号，商户网站订单系统中唯一订单号，必填，支付宝不允许有两个相同的订单号        // 使用uuid生成 避免重复
        //aliPay.setOut_trade_no(UUID.randomUUID().toString());
        Integer idd= Integer.valueOf(aliPay.getPpNo());
        DrugMoney drugMoney = drugMoneyMapper.queryPpNo(idd);



        if(drugMoney!=null) {
            String CkNo = drugMoney.getPpNo1();        // 付款金额，必填
            BigDecimal total_amount = drugMoney.getPrice().multiply(BigDecimal.valueOf(drugMoney.getBuyCount()));        // 订单名称，必填
            String subject =drugMoney.getDrugName();       // 商品描述，可空
            String body = drugMoney.getDrugName();        // 设置 业务参数 是一个json对象
            // 这个json对象 支付宝后台回去识别，根据这些参数进行处理，例如 金额，订单名称，商品描述
            request.setBizContent("{\"out_trade_no\":\"" + CkNo + "\","
                    + "\"total_amount\":\"" + total_amount + "\","
                    + "\"subject\":\"" + subject + "\","
                    + "\"body\":\"" + body + "\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

            // 支付完以后跳转的地址

            //    request.setReturnUrl("http://localhost:8098/checkMoney");
            // 3. 客户端执行请求        // 客户端执行请求，拿到响应的结果，返回给浏览器
            String form = "";
            try {            // 调用阿里的SDK生成表单
                // 会收到支付宝的响应，响应的是一个页面，一开始是登陆，然后显示金额，让用户输入密码进行付款
                form = alipayClient.pageExecute(request).getBody();
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            httpResponse.setContentType("text/html;charset=" + CHARSET);
            // 直接将完整的表单html输出到页面
            httpResponse.getWriter().write(form);
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
            drugMoneyMapper.updateStatus(drugMoney.getPpNo1());


        }}
    @RequestMapping("recharge")
    public void pay4(PayVO aliPay, HttpServletResponse httpResponse) throws Exception {
        // 1、根据支付宝的配置生成一个支付客户端 客户端用于去调用支付宝的API        // 官方写法
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        // 2、创建一个支付请求对象
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();        // 设置回调接口
        request.setNotifyUrl(aliPayConfig.getNotifyUrl1());
        // 商户订单号，商户网站订单系统中唯一订单号，必填，支付宝不允许有两个相同的订单号        // 使用uuid生成 避免重复
        //aliPay.setOut_trade_no(UUID.randomUUID().toString());



        if(aliPay!=null) {
            SnowflakeIdGenerator sfg=new SnowflakeIdGenerator();
            long prNo=sfg.nextId();




            String RsNo = String.valueOf(prNo);        // 付款金额，必填
            BigDecimal total_amount = aliPay.getMoney();        // 订单名称，必填
            String subject = "支付宝充值";       // 商品描述，可空
            String body = "支付宝充值";        // 设置 业务参数 是一个json对象
            // 这个json对象 支付宝后台回去识别，根据这些参数进行处理，例如 金额，订单名称，商品描述
            request.setBizContent("{\"out_trade_no\":\"" + RsNo + "\","
                    + "\"total_amount\":\"" + total_amount + "\","
                    + "\"subject\":\"" + subject + "\","
                    + "\"body\":\"" + body + "\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

            // 支付完以后跳转的地址

                request.setReturnUrl("http://localhost:8098/home");
            // 3. 客户端执行请求        // 客户端执行请求，拿到响应的结果，返回给浏览器
            String form = "";
            try {            // 调用阿里的SDK生成表单
                // 会收到支付宝的响应，响应的是一个页面，一开始是登陆，然后显示金额，让用户输入密码进行付款
                form = alipayClient.pageExecute(request).getBody();
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            httpResponse.setContentType("text/html;charset=" + CHARSET);
            // 直接将完整的表单html输出到页面
            httpResponse.getWriter().write(form);
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();

            RechargeMoney rechargeMoney = new RechargeMoney();
            rechargeMoney.setPrMoney(aliPay.getMoney());
            rechargeMoney.setPrCaseid(Integer.valueOf(aliPay.getPpNo()));
            rechargeMoney.setPrNo(String.valueOf(prNo));
            rechargeMoneyMapper.add(rechargeMoney);
            Withdrawal withdrawal = drugPatientMapper.queryByPurse(Integer.valueOf(aliPay.getPpNo()));
            if(withdrawal!=null) {

                withdrawal.setPurse(withdrawal.getPurse().add(aliPay.getMoney()));
                withdrawal.setDwCaseId(Integer.valueOf(aliPay.getPpNo()));
                withdrawal.setRecharge(withdrawal.getRecharge().add(aliPay.getMoney()));


                drugPatientMapper.update(withdrawal);
            }



        }}
    @RequestMapping("out")
    public void pay5(PayVO aliPay, HttpServletResponse httpResponse) throws Exception {
        // 1、根据支付宝的配置生成一个支付客户端 客户端用于去调用支付宝的API        // 官方写法
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        // 2、创建一个支付请求对象
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();        // 设置回调接口
        request.setNotifyUrl(aliPayConfig.getNotifyUrl1());
        // 商户订单号，商户网站订单系统中唯一订单号，必填，支付宝不允许有两个相同的订单号        // 使用uuid生成 避免重复
        //aliPay.setOut_trade_no(UUID.randomUUID().toString());



        if(aliPay!=null) {
            SnowflakeIdGenerator sfg=new SnowflakeIdGenerator();
            long prNo=sfg.nextId();




            String RsNo = String.valueOf(prNo);
            // 获取金额
            BigDecimal amount = aliPay.getMoney();

            // 创建一个表示-1的BigDecimal对象
            BigDecimal negativeOne = new BigDecimal("-1");

            // 使用multiply方法将amount乘以-1
            BigDecimal total_amount = amount.multiply(negativeOne); // 付款金额，必填
                  // 订单名称，必填
            String subject = "支付宝充值";       // 商品描述，可空
            String body = "支付宝充值";        // 设置 业务参数 是一个json对象
            // 这个json对象 支付宝后台回去识别，根据这些参数进行处理，例如 金额，订单名称，商品描述
            request.setBizContent("{\"out_trade_no\":\"" + RsNo + "\","
                    + "\"total_amount\":\"" + total_amount + "\","
                    + "\"subject\":\"" + subject + "\","
                    + "\"body\":\"" + body + "\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

            // 支付完以后跳转的地址

            request.setReturnUrl("http://localhost:8098/home");
            // 3. 客户端执行请求        // 客户端执行请求，拿到响应的结果，返回给浏览器
            String form = "";
            try {            // 调用阿里的SDK生成表单
                // 会收到支付宝的响应，响应的是一个页面，一开始是登陆，然后显示金额，让用户输入密码进行付款
                form = alipayClient.pageExecute(request).getBody();
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            httpResponse.setContentType("text/html;charset=" + CHARSET);
            // 直接将完整的表单html输出到页面
            httpResponse.getWriter().write(form);
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();

            RechargeMoney rechargeMoney = new RechargeMoney();
            rechargeMoney.setPrMoney(aliPay.getMoney());
            rechargeMoney.setPrCaseid(Integer.valueOf(aliPay.getPpNo()));
            rechargeMoney.setPrNo(String.valueOf(prNo));
            rechargeMoneyMapper.add(rechargeMoney);
            Withdrawal withdrawal = drugPatientMapper.queryByPurse(Integer.valueOf(aliPay.getPpNo()));
            if(withdrawal!=null) {

                withdrawal.setPurse(withdrawal.getPurse().subtract(aliPay.getMoney()));
                withdrawal.setDwCaseId(Integer.valueOf(aliPay.getPpNo()));
                withdrawal.setRecharge(total_amount);


                drugPatientMapper.update(withdrawal);
            }



        }}





}





